<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>力导向图</title>
</head>
<body>

<script src="../node_modules/d3/build/d3.js"></script>
<script>

  
  let width = 600, height = 500,
    nodes = [{name: "桂林"}, {name: "广州"}, {name: "厦门"}, {name: "杭州"},
      {name: "上海"}, {name: "青岛"}, {name: "天津"}],
    edges = [{source: 0, target: 1}, {source: 0, target: 2},
      {source: 0, target: 3}, {source: 1, target: 4},
      {source: 1, target: 5}, {source: 1, target: 6}];

  let svg = d3.select('body').append('svg').attr('width', width).attr('height', height);
  //布局
  let simulate = d3.forceSimulation(nodes)
    .force('link', d3.forceLink(edges).distance(100))// 连线??
    .force('charge', d3.forceManyBody()) //建立一個相互作用力模型:正值互相吸引，負值相互排斥
    .force('center', d3.forceCenter(width / 2, height / 2));
  let colors = d3.scaleOrdinal(d3.schemeCategory20);

  // 画线
  let svg_lines = svg.selectAll('line').data(edges).enter().append('line')
    .style('stroke', 'red').style('stroke-width', '3');
  // 画节点
  let svg_nodes = svg.selectAll('circle').data(nodes).enter().append('circle')
    .attr('r', 20)
    .attr('fill', function (d, i) {
      return colors(i);
    })
    .attr('cx', function (d, i) {
      return d.x;
    })
    .attr('cy', function (d, i) {
      return d.y;
    });

  // 文字
  let svg_text = svg.selectAll('text').data(nodes).enter().append('text')
    .attr('dx', -15).attr('dy', 5).style('fill', '#000')
    .text(function (d) {
      return d.name;
    });

  function draw () {
    svg_lines.attr('x1', function (d) {
      return d.source.x
    })
      .attr('y1', function (d) {
        return d.source.y
      })
      .attr('x2', function (d) {
        return d.target.x
      })
      .attr('y2', function (d) {
        return d.target.y
      });

    svg_nodes.attr('cx', function (d, i) {
      return d.x;
    })
      .attr('cy', function (d, i) {
        return d.y;
      });

    svg_text.attr("x", function (d) {
      return d.x;
    })
      .attr("y", function (d) {
        return d.y;
      });
  }

  simulate.on('tick', draw);


</script>

</body>
</html>